﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using System.IO;

namespace PSE.Framework.Communication.Spb.Common
{
    public class Serializer
    {
        public static byte[] Serialize(Type type, object message, string xmlNamespace)
        {
            StringBuilder sb = new StringBuilder();

            XmlWriterSettings settings = new XmlWriterSettings();
            settings.OmitXmlDeclaration = true;

            //Impede que seja gerado no xml os atributos xmlns:xsi e xmlns:xsd
            XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
            ns.Add("", xmlNamespace);

            XmlWriter writer = XmlWriter.Create(sb, settings);
            
            XmlSerializer s = new XmlSerializer(type);

            s.Serialize(writer, message, ns);

            //TODO: Procurar solucao mais elegante, uma vez que caso seja enviado no formato original, o 
            //destinatario nao consegue tratar o no da mensagem.
            sb.Replace("<NUOp />", "<NUOp></NUOp>");
            sb.Replace("<NUOp/>", "<NUOp></NUOp>");
            
            byte[] buffer = System.Text.Encoding.UTF8.GetBytes(sb.ToString());
            return buffer;

        }

        public static object Deserialize(Type type, object message)
        {
            XmlSerializer s = null;
            System.Xml.XmlReader reader = null;
            object deserializedObject = null;

            try
            {
                s = new XmlSerializer(type);

                using (MemoryStream m = new System.IO.MemoryStream((byte[])message))
                {
                    reader = System.Xml.XmlReader.Create(new System.IO.StreamReader(m, Encoding.Unicode));
                    deserializedObject = s.Deserialize(reader);
                }
            }
            finally
            {
                if (reader != null)
                    reader.Close();
            }

            return deserializedObject;
        }
    }
}
